home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Panorama / Panorama - Disk 01 (1986-02-15)(Pacific North-West Amigas Club)[h AFL][b corrupt files].zip / Panorama - Disk 01 (1986-02-15)(Pacific North-West Amigas Club)[h AFL][b corrupt files].adf / mand1.c < prev    next >
Text File  |  1989-10-24  |  12KB  |  445 lines

  1. /*
  2.                    MAND1.C - Graphics routines
  3.              Mandelbrot Self-Squared Dragon Generator
  4.                     For the Commodore Amiga
  5.                          Version 2.01
  6.  
  7.              Copyright (C) 1985, Robert S. French
  8.             Vastly Enhanced by =RJ Mical=  1985/86
  9.             Copyright (C) 1986,  =Robert J. Mical=
  10.                  Placed in the Public Domain
  11.  
  12.  
  13. This program may be distributed free of charge as long as the above
  14. notice is retained.
  15.  
  16. */
  17.  
  18.  
  19. #include "mand.h"
  20.  
  21.  
  22. extern int MathBase, MathTransBase;
  23.  
  24. extern struct Menu MainMenu[MENU_COUNT];
  25. extern struct MenuItem OptionsItems[OPTIONS_COUNT];
  26.  
  27.  
  28. extern SHORT Color0, Color1, Color2;
  29. extern SHORT UserPalette[29];
  30.  
  31. /*----------------------*/
  32. /* Graphics definitions */
  33.  
  34. extern struct   GfxBase       *GfxBase;
  35. extern struct   IntuitionBase *IntuitionBase;
  36.  
  37. extern struct   RastPort      *rp,*rp2;
  38. extern struct   ViewPort      *vp;
  39.  
  40. extern struct   Window        *w,*w2, *ColorWindow;
  41. extern struct   Screen        *screen;
  42. extern struct   IntuiMessage  *message;
  43.  
  44. extern long last_color;
  45.  
  46. extern BOOL SettingCenter, SettingBoxSize, SetBoxProportional;
  47.  
  48. /*----------------------------------*/
  49. /* Miscellaneous Global Definitions */
  50.  
  51. extern union kludge {
  52.    float f;
  53.    int i;
  54. } start_r,end_r,start_i,end_i;  /* Block bounds for set */
  55. extern int max_x,max_y;  /* Graphics window size */
  56. extern int max_count,color_inc,color_offset,color_set,color_mode,color_div;
  57. extern int color_inset,func_num;
  58.  
  59. extern int v_starty,max_mem;
  60. extern long v_offset;
  61. extern UWORD *color_table,*v_mand_store;
  62.  
  63. extern int modified,want_read;
  64.  
  65. extern FILE *console,*v_fp,*redir_fp;
  66.  
  67. extern SHORT ZoomCenterX, ZoomCenterY, ZoomBoxSizeX, ZoomBoxSizeY;
  68. extern SHORT ZoomBoxStartX, ZoomBoxStartY;
  69.  
  70.  
  71. /*----------------*/
  72. /* Color routines */
  73.  
  74. init_colors()
  75. {
  76.    switch (color_set) {
  77.       case 0: init_cincr(); break;
  78.       case 1: init_c7rot(); break;
  79.       case 2: copy_userpalette(); break;
  80.    }
  81. }
  82.  
  83. init_cincr()
  84. /* this routine initializes the color table with sequential values from
  85.  * 0 to 4095
  86.  */
  87. {
  88.    UWORD i;
  89.  
  90.    for (i=0;i<4096;i++)
  91.       *(color_table + i) = i;
  92. }
  93.  
  94.  
  95. init_c7rot()
  96. /* this routine initializes the color table with this pattern:
  97.  * 0 = 0
  98.  * 1-15 = unit steps of blue
  99.  * 16-30 = unit steps of green
  100.  * 31-45 = unit steps of red
  101.  * 46-60 = unit steps of sky sky blue (blue and green)
  102.  * 61-75 = unit steps of purple (blue and red)
  103.  * 76-90 = unit steps of yellow (green and red)
  104.  * 91-115 = unit steps of white (all colors)
  105.  */
  106. {
  107.    UWORD i,j,*base;
  108.  
  109.    base = color_table;
  110.    *(base++) = 0;
  111.  
  112.    for (j = 0; j < 39; j++) {
  113.       for (i = 1; i < 16; i++)
  114.          *(base++) = i; /* gimme the blues */
  115.       for (i = 1; i < 16; i++)
  116.          *(base++) = i << 4; /* these are the greens */
  117.       for (i = 1; i < 16; i++)
  118.          *(base++) = i << 8; /* the reds */
  119.       for (i = 1; i < 16; i++)
  120.          *(base++) = i | (i << 4); /* blue and green */
  121.       for (i = 1; i < 16; i++)
  122.          *(base++) = i | (i << 8); /* blue and red */
  123.       for (i = 1; i < 16; i++)
  124.          *(base++) = (i << 4) | (i << 8); /* green and red */
  125.       for (i = 1; i < 16; i++)
  126.          *(base++) = i | (i << 4) | (i << 8); /* all three */
  127.    }
  128. }
  129.  
  130.  
  131. copy_userpalette()
  132. {
  133.     SHORT i;
  134.  
  135.     for (i = 0; i <= 28; i++)
  136.         *(color_table + color_offset + (i + 1) * color_inc) = UserPalette[i];
  137. }
  138.  
  139.  
  140. gen_mand()
  141. {
  142.    void write_out();
  143.  
  144.    int x_coord,y_coord,count;
  145.    union kludge x_gap,y_gap,z_r,z_i,u_r,u_i,temp,temp2,temp3,const0;
  146.    union kludge const1,const2,const12;
  147.    ULONG class;
  148.    USHORT code;
  149.    int returncode;
  150.    int z_r_squared, z_i_squared;
  151.  
  152.     /* if there was a display open, close it now */
  153.    CloseDisplay();
  154.  
  155.    /* show the current settings! */
  156.    CurrentSettings();
  157.  
  158.    /* reset the display variables: */
  159.    SettingCenter = SettingBoxSize = FALSE;
  160.  
  161.    if (v_fp) {
  162.       fclose(v_fp);
  163.       v_fp = NULL;
  164.    }
  165.  
  166.    v_fp = fopen("Mandelbrot.temp.file","w+");
  167.    if (v_fp == NULL) {
  168.       abort("Can't open temporary file!");
  169.    }
  170.  
  171.    v_starty = 1;
  172.    v_offset = 0L;
  173.    modified = FALSE;
  174.    want_read = FALSE;
  175.    ZoomCenterX = (max_x >> 1);
  176.    ZoomCenterY = (max_y >> 1);
  177.    ZoomBoxSizeX = max_x;
  178.    ZoomBoxSizeY = max_y;
  179.  
  180.    if (open_winds())
  181.       {
  182.       returncode = 1;
  183.       goto OPEN_W_RETURN;
  184.       }
  185.  
  186.    x_gap.i = SPDiv(SPFlt(max_x),SPSub(start_r.i,end_r.i));
  187.    y_gap.i = SPDiv(SPFlt(max_y),SPSub(start_i.i,end_i.i));
  188.  
  189.    const0.i = SPFlt(0);
  190.    const1.i = SPFlt(1);
  191.    const2.i = SPFlt(2);
  192.    const12.i = SPDiv(SPFlt(2),SPFlt(1));
  193.  
  194.    for (y_coord = 0; y_coord < max_y; y_coord++)
  195.       {
  196.       last_color = 0xfff;
  197.       v_pos_line(y_coord);
  198.       modified = TRUE;
  199.       for (x_coord = 0; x_coord < max_x; x_coord++)
  200.          {
  201.          while (message = (struct IntuiMessage *)GetMsg(w->UserPort))
  202.             {
  203.             class = message->Class;
  204.             code  = message->Code;
  205.             ReplyMsg(message);
  206.             if (class == MENUPICK)
  207.                {
  208.                /* the menu strip is hacked up to a minimal set during gen_m */
  209.                switch MENUNUM(code)
  210.                   {
  211.                   case 0:
  212.                      switch ITEMNUM(code)
  213.                         {
  214.                         case 0:
  215.                            returncode = 0;
  216.                            goto OPEN_W_RETURN;
  217.                         case 1:
  218.                            CloseDisplay();
  219.                            fclose(v_fp);
  220.                            v_fp = NULL;
  221.                            returncode = 1;
  222.                            goto OPEN_W_RETURN;
  223.                         }
  224.                      break;
  225.                   }
  226.                }
  227.             }
  228.  
  229.          if (func_num == 0)
  230.             z_r.i = const0.i;
  231.          else
  232.             z_r.i = const12.i;
  233.  
  234.          z_i.i = const0.i;
  235.          u_r.i = SPAdd(start_r.i,SPMul(SPFlt(x_coord),x_gap.i));
  236.          u_i.i = SPAdd(start_i.i,SPMul(SPFlt(max_y-y_coord-1),y_gap.i));
  237.          for (count = 0; count < max_count; count++)
  238.             {
  239.             /* By setting these variables and reusing the results below,
  240.              * we save approximately 10% execution time in this 
  241.              * innermost of inner loops.
  242.              */
  243.             z_r_squared = SPMul(z_r.i, z_r.i);
  244.             z_i_squared = SPMul(z_i.i, z_i.i);
  245.             if ( SPFix(SPAdd(z_r_squared, z_i_squared)) >= 4 ) break;
  246.             if (func_num == 0)
  247.                {  /* z = z^2-u */
  248.                temp.i = SPSub(u_r.i, SPSub(z_i_squared, z_r_squared));
  249.                z_i.i = SPSub(u_i.i, SPMul(SPMul(const2.i,z_r.i), z_i.i));
  250.                z_r = temp;
  251.                }
  252.             else if (func_num == 1)
  253.                {  /* z = uz(1-z) */
  254.                temp2.i = SPSub(z_r.i,const1.i);
  255.                temp3.i = SPNeg(z_i.i);
  256.                temp.i = SPSub(SPMul(temp3.i,z_i.i),SPMul(temp2.i,z_r.i));
  257.                z_i.i = SPAdd(SPMul(temp2.i,z_i.i),SPMul(temp3.i,z_r.i));
  258.                z_r = temp;
  259.                temp.i = SPSub(SPMul(z_i.i,u_i.i),SPMul(z_r.i,u_r.i));
  260.                z_i.i = SPAdd(SPMul(z_r.i,u_i.i),SPMul(z_i.i,u_r.i));
  261.                z_r = temp;
  262.                }
  263.             }
  264.  
  265.          if (count >= max_count)
  266.             count = 0;
  267.          *(v_mand_store+(y_coord-v_starty)*max_x+x_coord) = count;
  268.          write_out(count,x_coord,y_coord);
  269.          }
  270.  
  271.    }
  272.  
  273.    /* successful return with window opened */
  274.    returncode = 0;
  275.    DisplayBeep(NULL); /* hey, we're done! */
  276.    /* Now that we're drawing the primary display, 
  277.     * restore the entire menu system 
  278.     */
  279.  
  280. OPEN_W_RETURN:
  281.    if (returncode == 0)
  282.       {
  283.       MainMenu[MENU_OPTIONS].NextMenu = &MainMenu[MENU_ZOOM];
  284.       MainMenu[MENU_OPTIONS].FirstItem = &OptionsItems[0];
  285.       SetMenuStrip(w, &MainMenu[0]);
  286.       }
  287.  
  288.    return(returncode);
  289. }
  290.  
  291. disp_mand()
  292. {
  293.    void write_out();
  294.  
  295.    int x_coord,y_coord,count;
  296.  
  297.    if (open_winds())
  298.       return (1);
  299.  
  300.    want_read = TRUE;
  301.  
  302.    for (y_coord=0;y_coord<max_y;y_coord++) {
  303.       last_color = 0xfff;
  304.       v_pos_line(y_coord);
  305.       for (x_coord=0;x_coord<max_x;x_coord++) {
  306.          count = *(v_mand_store+(y_coord-v_starty)*max_x+x_coord);
  307.          write_out(count,x_coord,y_coord);
  308.       }
  309.    }
  310.  
  311.    return (0);
  312. }
  313.  
  314. void write_out(count,x,y)
  315. int count,x,y;
  316. {
  317.    void ham_write();
  318.    SHORT modulus;
  319.    int color;
  320.  
  321.    y += STARTY;
  322.  
  323.    if (!(color_mode & NOT_HOLDANDMODIFY)) {
  324.       if (count == 0)
  325.          color = color_inset;
  326.       else
  327.          color = count * color_inc + color_offset;
  328.       ham_write(*(color_table+color),x,y);
  329.    }
  330.    else /* we're not hold-and-modify, so ... */ {
  331.       if (color_mode & HIRES_MODE) modulus = 13;
  332.       else modulus = 29;
  333.  
  334.       if (count == 0) color = 2;
  335.       else color = (((count - 1) / color_div) % modulus) + 3;
  336.       SetAPen(rp, color);
  337.       WritePixel(rp, x, y);
  338.    }
  339. }
  340.  
  341. void ham_write(color, x, y)
  342. int color;
  343. int x, y;
  344. {
  345.    if ((color & 0xf00) != (last_color & 0xf00)) {
  346.       SetAPen(rp,((color & 0xf00) >> 8) + 0x20);
  347.       WritePixel(rp,x,y);
  348.       last_color = (last_color & 0xff) | (color & 0xf00);
  349.       return;
  350.    }
  351.  
  352.    if ((color & 0xf0) != (last_color & 0xf0)) {
  353.       SetAPen(rp,((color & 0xf0) >> 4) + 0x30);
  354.       WritePixel(rp,x,y);
  355.       last_color = (last_color & 0xf0f) | (color & 0xf0);
  356.       return;
  357.    }
  358.  
  359.    SetAPen(rp,(color & 0xf) + 0x10);
  360.    WritePixel(rp,x,y);
  361.    last_color = (last_color & 0xff0) | (color & 0xf);
  362.    return;
  363. }
  364.  
  365.  
  366. DrawZoomCenter()
  367. {
  368.     DrawCross(ZoomCenterX, ZoomCenterY);
  369. }
  370.  
  371. DrawDisplayCenter()
  372. {
  373.     DrawCross(max_x >> 1, max_y >> 1);
  374. }
  375.  
  376.  
  377. DrawCross(x, y)
  378. SHORT x, y;
  379. {
  380.    SetDrMd(w->RPort, COMPLEMENT);
  381.    Move(w->RPort, 0, y);
  382.    Draw(w->RPort, max_x, y);
  383.    Move(w->RPort, x, 0);
  384.    Draw(w->RPort, x, max_y);
  385. }
  386.  
  387.  
  388. RecalcZoomBox()
  389. {
  390.     ZoomBoxSizeY = (abs(w->MouseY - ZoomCenterY) << 1) + 1;
  391.     if (w->MouseY < ZoomCenterY) ZoomBoxStartY = w->MouseY;
  392.     else ZoomBoxStartY = ZoomCenterY - ((ZoomBoxSizeY - 1) >> 1);
  393.  
  394.     /* if SetBoxProportional, size X proportional to Y */
  395.     if (SetBoxProportional)
  396.         {
  397.         ZoomBoxSizeX = (ZoomBoxSizeY * 8) / 5;
  398.         ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1);
  399.         }
  400.     else
  401.         {
  402.         ZoomBoxSizeX = (abs(w->MouseX - ZoomCenterX) << 1) + 1;
  403.         if (w->MouseX < ZoomCenterX) ZoomBoxStartX = w->MouseX;
  404.         else ZoomBoxStartX = ZoomCenterX - ((ZoomBoxSizeX - 1) >> 1);
  405.         }
  406. }
  407.  
  408.  
  409. DrawZoomBox()
  410. {
  411.    SetDrMd(w->RPort, COMPLEMENT);
  412.    DrawBox(w->RPort, ZoomBoxStartX, ZoomBoxStartY, 
  413.          ZoomBoxStartX + ZoomBoxSizeX - 1,
  414.          ZoomBoxStartY + ZoomBoxSizeY - 1);
  415.  
  416. }
  417.  
  418.  
  419. CloseDisplay()
  420. {
  421.    if (w) CloseWindow(w);
  422.    if (w2) CloseWindow(w2);
  423.    if (ColorWindow) CloseWindow(ColorWindow);
  424.    if (screen) CloseScreen(screen);
  425.    w = NULL;
  426.    screen = NULL;
  427. }
  428.  
  429.  
  430.  
  431. DrawBox(rp, x1, y1, x2, y2)
  432. struct RastPort *rp;
  433. SHORT x1, y1, x2, y2;
  434. /* draws a box without overlapping the edges (in case of complement mode) */
  435. {
  436.     Move(rp, x1, y1 + SIGN(y2 - y1));
  437.     Draw(rp, x1, y2);  
  438.     Move(rp, x1 + SIGN(x2 - x1), y2);
  439.     Draw(rp, x2, y2);  
  440.     Move(rp, x2, y2 - SIGN(y2 - y1));
  441.     Draw(rp, x2, y1); 
  442.     Move(rp, x2 - SIGN(x2 - x1), y1);
  443.     Draw(rp, x1, y1);
  444. }
  445.